home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk.zip / MAWK.MAN < prev    next >
Text File  |  1991-04-23  |  21KB  |  640 lines

  1.  
  2.                               Mawk Manual 
  3.  
  4. Mawk implements the awk language as defined in Aho, Kernighan and 
  5. Weinberger, The AWK Programming Language, Addison-Wesley, 1988, ISBN 
  6. 0-201-07981-X, hereafter called the AWK book.  Chapter 2 serves as a 
  7. reference to the language and the rest (8 total chapters) provides a 
  8. wide range of examples and applications.  This book is must reading to 
  9. understand the versatility of the language.  
  10.  
  11. The 1988 version of the language is sometimes called new awk as opposed 
  12. to the 1977 version (awk or old awk.) Virtially every Unix system has 
  13. old awk, somewhere in the documentation will be an (old) awk tutorial 
  14. (probably in support tools).  If you use (old) awk, the transition to 
  15. new awk is easy.  The language has been extended and ambiguous points 
  16. clarified, but old awk programs still run under new awk.  
  17.  
  18. This manual assumes you know (old) awk, and hence concentrates on the 
  19. new features of awk.  Feature xxx is new means xxx was added to the 1988
  20. version.  
  21.  
  22. Experienced new awk users should read sections 9 and 12, and skim 
  23. sections 7 and 8.  
  24.  
  25. 1. Command line
  26.  
  27.     mawk [-Fs] 'program'  optional_list_of_files
  28.     mawk [-Fs] -f program_file  optional_list_of_files
  29.  
  30. 2. Program blocks
  31.  
  32.     Program blocks are of the form:
  33.  
  34.     pattern { action }
  35.  
  36.     pattern can be:
  37.  
  38.     regular_expression
  39.     expression
  40.     ( pattern )
  41.     ! pattern
  42.     pattern || pattern
  43.     pattern && pattern
  44.  
  45.     pattern , pattern  (range pattern)
  46.     BEGIN
  47.     END
  48.  
  49. Range, BEGIN and END patterns cannot be combined to form new patterns.  
  50. BEGIN and END patterns require an action; otherwise, if action is 
  51. omitted it is implicitly { print }.  
  52.  
  53.     NR==2    {  print }  # prints line number 2
  54.     NR==2             # also prints line number 2
  55.  
  56. If pattern is omitted then action is always applied.
  57.  
  58.     { print $NF }
  59.  
  60. prints the last field of every record.
  61.  
  62. 3. Statement format and loops
  63.  
  64. Statements are terminated by newlines, semi-colons or both.  Groups of 
  65. statements are blocked via { ...  } as in C.  The last statement in a 
  66. block doesn't need a terminator.  Blank lines have no meaning; an empty 
  67. statement is terminated with a semi-colon.  Long statements can be 
  68. continued with a backslash, \.  A statement can be broken without a 
  69. backslash after a comma, left brace, &&, ||, do, else, the right 
  70. parenthesis of an if, while or for statement, and the right parenthesis 
  71. of a function definition.  
  72.  
  73. Loops are for(){}, while(){} and do{}while() as in C.  
  74.  
  75. 4. Expression syntax
  76.  
  77. The expression syntax and grouping of the language is similar to C.  
  78. Primary expressions are numeric constants, string constants, variables, 
  79. arrays and functions.  Complex expressions are composed with the 
  80. following operators in order of increasing precedence.  
  81.  
  82.     assignment: = += -+ *= /= ^=
  83.     conditional:  ? :
  84.     logical or:   ||
  85.     logical and:  &&
  86.     array membership :   in
  87.     matching :   ~   !~
  88.     relational :  <  >   <=  >=  ==  !=
  89.     concatenation:   (no explicit operator)
  90.     add ops:  +  -
  91.     mul ops:  *  /  % 
  92.     unary  :  +  -
  93.     logical not :  !
  94.     exponentiation:  ^
  95.     inc and dec:  ++ -- (both post and pre)
  96.     field:  $
  97.  
  98. 5. Builtin variables.
  99.  
  100. The following variables are built-in and initialized before program 
  101. execution.  
  102.  
  103.     ARGC    number of command line arguments
  104.     ARGV    array of command line arguments, 0..ARGC-1
  105.     FILENAME    name of the current input file
  106.     FNR         current record number in the current input file
  107.     FS        splits records into fields as a regular expression
  108.     NF        number of fields in the current record, i.e., $0
  109.     NR        current record number in the total input stream
  110.     OFMT    format for printing numbers; initially = "%.6g"
  111.     OFS        inserted between fields on output, initially = " "
  112.     ORS        terminates each record on output, initially = "\n"
  113.     RLENGTH     length of the last call to the built-in function, match()
  114.     RS        input record separator, initially = " "
  115.     RSTART    index of the last call to match()
  116.     SUBSEP    used to build multiple array subscripts, initially = "\034"
  117.     VERSION     Mawk version, unique to mawk.
  118.  
  119. ARGC, ARGV, FNR, RLENGTH, RSTART and SUBSEP are new.  
  120.  
  121. The current input record is stored in the field, $0.  The fields of $0 
  122. determined by splitting with RS are stored in $1, $2, ..., $NF.  
  123.  
  124.  
  125. 6. Built-in Functions
  126.  
  127. String functions
  128.  
  129.     index(s,t)
  130.     length(s), length
  131.     split(s, A, r), split(s, A)
  132.     substr(s,i,n) , substr(s,i)
  133.     sprintf(format, expr_list)
  134.  
  135.     match(s,r)        returns the index where string s matches
  136.                 regular expression r or 0 if no match. As
  137.             a side effect, sets RSTART and RLENGTH.
  138.  
  139.     gsub(r, s, t)       Global substitution, every match of regular
  140.             expression r in variable t is replaced by s.
  141.             The number of matches/replacements is returned.
  142.  
  143.     sub(r, s, t)    Like gsub(), except at most one replacement.
  144.  
  145. Match(), gsub() and sub() are new.  If r is an expr it is coerced to 
  146. string and then treated as a regular expression.  In sub and gsub, t can
  147. be a variable, field or array element, i.e., it must have storage to 
  148. hold the modification.  Sub(r,s) and gsub(r,s) are the same as 
  149. sub(r,s,$0) and gsub(r,s,$0).  In the replacement string s, an & is 
  150. replaced by the matched piece and a literal & is obtained with \&.  
  151. E.g., 
  152.  
  153.         y = x = "abbc"
  154.         sub(/b+/, "B&B" , x)
  155.         sub(/b+/, "B\&B" , y)
  156.         print x, y
  157.  
  158. outputs:    aBbbBc aB&Bc
  159.  
  160.  
  161.  
  162.  
  163. Arithmetic functions
  164.  
  165.     atan2(y,x)        arctan of y/x between -pi and pi.
  166.     cos(x)
  167.     exp(x)
  168.     int(x)        x.dddd ->  x.0
  169.     log(x)
  170.     rand()        returns random number , 0 <= r < 1.
  171.     sin(x)
  172.     sqrt(x)
  173.     srand(x) , srand()  seeds random number generator, uses clock
  174.             if x is omitted.
  175.  
  176. Output functions
  177.  
  178.     print        writes  $0 ORS   to stdout.
  179.  
  180.     print expr1 , expr2 , ... , exprn
  181.             writes expr1 OFS expr2 OFS ... OFS exprn ORS to
  182.             stdout.
  183.  
  184.     printf format, expr_list
  185.             Acts like the C library function, writing to
  186.             stdout.  Supported conversions are
  187.             %c, %d, %e, %f, %g, %o, %s and %x.  
  188.             - , width and .prec are supported.
  189.             Dynamic widths can be built using string operations
  190.  
  191.  
  192. Output can be redirected 
  193.  
  194.    print[f]  > file
  195.          >> file
  196.          | command
  197.  
  198. File and command are awk expressions that are interpreted as a filename 
  199. or a shell command.  
  200.  
  201.  
  202. Input functions
  203.  
  204.     getline        read $0, update NF, NR and FNR.
  205.  
  206.     getline < file      read $0 from file, update NF.
  207.     getline var         read var from input stream, update NR, FNR.
  208.     getline var < file  read var from next record of file
  209.  
  210.     command | getline   read $0 from piped command, update NF.
  211.     command | getline var   read var from next record of piped command.
  212.  
  213. (Old) awk had getline, the redirection facilities are new.
  214.  
  215.     Files or commands are closed with
  216.  
  217.     close(expr)
  218.  
  219. where expr is command or file as a string.  Close returns 0 if expr was 
  220. in fact an open file or command else -1.  Close is needed if you want to
  221. reread a file, rerun a command, have a large number of output files 
  222. without mawk running out of resources or wait for an output command to 
  223. finish.  Here is an example of the last case: 
  224.  
  225.     { ....  do some processing on each input line
  226.       #  send the processed line to sort
  227.       print | "sort > temp_file"
  228.  
  229.     }
  230.  
  231.     END { # reread the sorted input
  232.       close( "sort > temp_file")  # makes sure sort is finished
  233.  
  234.       cnt=1
  235.       while ( getline line[cnt++] < "temp_file"  > 0 )  ;  
  236.       system( "rm temp_file" )  # cleanup
  237.  
  238.       ... process line[1], line[2] ... line[cnt-1]
  239.     }
  240.  
  241. The system() function executes a command and returns the command's exit 
  242. status.  Mawk uses the shell in the environment variable SHELL to 
  243. execute system or command pipelines; defaulting to "/bin/sh" if SHELL is
  244. not set.  
  245.  
  246.  
  247. 7. String constants
  248.  
  249. String constants are written as in C.
  250.  
  251.  
  252.     "This is a string with a newline at the end.\n"
  253.  
  254. Strings can be continued across a line by escaping (\) the newline.  The
  255. following escape sequences are recognized.  
  256.  
  257.     \\        \
  258.     \"        "
  259.     \'        '
  260.     \a        alert, ascii 7
  261.     \b        backspace, ascii 8
  262.     \t        tab, ascii 9
  263.     \n        newline, ascii 10
  264.     \v        vertical tab, ascii 11
  265.     \f        formfeed, ascii 12
  266.     \r        carriage return, ascii 13
  267.     \ddd        1, 2 or 3 octal digits for ascii ddd
  268.  
  269.     \xhh        1 or 2 hex digits for ascii  hh
  270.  
  271. If you escape any other character \c, you get \c, i.e.  the escape is 
  272. ignored.  Mawk is different than most awks here; the AWK book says \c is
  273. c.  The reason mawk chooses to be different is for easier conversion of 
  274. strings to regular expressions.  
  275.  
  276.  
  277. 8. Regular expressions
  278.  
  279. Awk notation for regular expressions is in the style of egrep(1).  In 
  280. awk, regular expressions are enclosed in / ...  /.  A regular expression
  281. /r/, is a set of strings.  
  282.  
  283.         s ~ /r/
  284.  
  285. is an awk expression that evaluates to 1 if an element of /r/ is a 
  286. substring of s and evaluates to 0 otherwise.  ~ is called the match 
  287. operator and the expression is read "s matches r".  
  288.  
  289.        s ~ /^r/   is 1 if some element of r is a prefix of s.
  290.        s ~ /r$/   is 1 if some element of r is a suffix of s.
  291.        s ~ /^r$/  is 1 if s is an element of r.
  292.  
  293. Replacing ~ by !~ , the not match operator, reverses the meanings.  In 
  294. patterns, /r/ and !/r/ are shorthand for $0 ~ /r/ and $0 !~ /r/.  
  295.  
  296. Regular expressions are combined by the following rules.
  297.  
  298.     //  stands for the one element set "" (not the empty set).
  299.     /c/ for a character c is the one element set "c".
  300.  
  301.     /rs/  is all elements of /r/ concatenated with all 
  302.           elements of /s/.
  303.  
  304.     /r|s/ is the set union of /r/ and /s/.
  305.  
  306.     /r*/  called the closure of r is // union /rr/ union /rrr/ ...
  307.           In words, r repeated zero or more times.
  308.  
  309. The above operations are sufficient to describe all regular expressions,
  310. but for ease of notation awk defines additional operations and notation.
  311.  
  312.     /r?/  // union /r/.  In words r 0 or 1 time.
  313.     /r+/  Positive closure of r.  R 1 or more times.
  314.     (r)   Same as r -- allows grouping.
  315.     .     Stands for any character (for mawk this means 
  316.           ascii 1 through ascii 255)
  317.     [c1c2..cn]    A character class same as (c1|c2|...|cn) where
  318.           ci's are single characters.
  319.  
  320.     [^c1c2..cn]   Complement of the class [c1c2..cn].  For mawk
  321.           complement in the ascii character set 1 to 255.
  322.  
  323. Ranges c1-cn are allowed in character classes.  For example,
  324.  
  325.     /[_a-zA-Z][_a-zA-Z0-9]*/
  326.  
  327. expresses the set of possible identifiers in awk.
  328.  
  329. The operators have increasing precedence:
  330.  
  331.        |
  332.        implicit concatenation
  333.        + * ?
  334.  
  335. So /a|b+/ means a or (1 or more b's), and /(a|b)+/ means (a or b) one or
  336. more times.  The so called regular expression metacharacters are \ ^ $ .
  337. [ ] | ( ) * + ? .  To stand for themselves as characters they have to be
  338. escaped.  (They don't have to be escaped in classes, inside classes the 
  339. meta-meaning is off).  The same escape sequences that are recognized in 
  340. strings (see above) are recognized in regular expressions.  For mawk, 
  341. the escape rule for \c changes to c.  
  342.  
  343. For example,
  344.  
  345.     /[ \t]*/   is optional space
  346.     /^[-+]?([0-9]+\.?|\.[0-9])[0-9]*([eE][-+]?[0-9]+)?$/
  347.            is numbers in the Awk language.
  348.            Note,  . must be escaped to have
  349.            its meaning as decimal point.
  350.  
  351. For building regular expressions, you can think of ^ and $ as phantom 
  352. characters at the front and back of every string.  So /(^a|b$|^A.*B$)/ 
  353. is the set of strings that start with a or end with b or (start with A 
  354. and end with B).  
  355.  
  356. Dynamic regular expressions are new.  You can write 
  357.  
  358.     x ~ expr
  359.  
  360. and expr is interpreted as a regular expression.  The result of x ~ y 
  361. can vary with the variable y; so 
  362.  
  363.     x ~ /a\+b/   and   x ~ "a\+b"
  364.  
  365. are the same, or are they? In mawk, they are; in some other awk's they 
  366. are not.  In the second expression, "a\+b" is scanned twice: once as a 
  367. string constant and then again as a regular expression.  In mawk the 
  368. first scan gives the four character string 'a' '\' '+' 'b' because mawk 
  369. treats \+ as \+; the second scan gives a regular expression matched by 
  370. the three character string 'a' '+' 'b' because on the second scan \+ 
  371. becomes +.  
  372.  
  373. If \c becomes c in strings, you need to double escape metacharacters, 
  374. i.e., write 
  375.  
  376.     x ~ "a\\+b".
  377.  
  378. Exercise: what happens if you double escape in mawk?
  379.  
  380. In strings if you only escape characters with defined escape sequences 
  381. such as \t or \n or meta-characters when you expect to use a string as a
  382. regular expression, then mawk's rules are intuitive and simple.  See 
  383. example/cdecl.awk and example/gdecl.awk for the same program with single
  384. and double escapes, the first is clearer.  
  385.  
  386.  
  387. 9. How Mawk splits lines, records and files.
  388.  
  389. Mawk uses the essentially the same algorithm to split lines into pieces 
  390. with split(), records into fields on FS, and files into records on RS.  
  391.  
  392. Split( s, A, sep ) splits string s into array A with separator sep as 
  393. follows: 
  394.  
  395.     Sep is interpreted as a regular expression.
  396.  
  397.     If s = "", there are no pieces and split returns 0.
  398.  
  399.     Otherwise s is split into pieces by the matches with sep
  400.     of positive length treated as a separator between pieces,
  401.     so the number of pieces is the number of matches + 1.
  402.     Matches of the null string do not split.
  403.     So sep = "b+" and sep = "b*" split the same although the
  404.     latter executes more slowly.
  405.  
  406.     Split(s, A) is the same as split(s, A, FS).
  407.     With mawk you can write sep as a regular expression, i.e.,
  408.     split(s, A, "b+") and split(s, A, /b+/) are the same.
  409.  
  410.     Sep = " " (a single space) is special.  Before the algorithm is
  411.     applied, white-space is trimmed from the front and back of s.
  412.     Mawk defines white-space as SPACE, TAB, FORMFEED, VERTICAL TAB
  413.     or NEWLINE, i.e [ \t\f\v\n].  Usually this means SPACE or TAB
  414.     because NEWLINE usually separates records, and the other
  415.     characters are rare.  The above algorithm
  416.     is then applied with sep = "[ \t\f\v\n]+".
  417.  
  418.     If length(sep) = 1, then regular expression metacharacters do
  419.     not have to be escaped, i.e. split(s, A, "+") is the same as
  420.     split(s, A, /\+/).
  421.  
  422.  
  423. Splitting records into fields works exactly the same except the pieces 
  424. are loaded into $1, $2 ...  $NF.  
  425.  
  426. Records are also the same, RS is treated as a regular expression.  But 
  427. there is a slight difference, RS is really a record terminator (ORS is 
  428. really a terminator also).  
  429.  
  430.     E.g., if FS = ":" and $0 = "a:b:" , then
  431.     NF = 3 and $1 = "a", $2 = "b" and $3 = "", but
  432.     if "a:b:" is the contents of an input file and RS = ":", then
  433.     there are two records "a" and "b".
  434.  
  435.     RS = " " does not have special meaning as with FS.
  436.  
  437.  
  438. Not all versions of (new) awk support RS as a regular expression.  This 
  439. feature of mawk is useful and improves performance.  
  440.  
  441.     BEGIN { RS = "[^a-zA-Z]+" 
  442.         getline
  443.         if ( $0 == "" ) NR = 0 
  444.         else word[1] = $0
  445.     }
  446.  
  447.     { word[NR] = $0 }
  448.  
  449.     END { ... do something with word[1]...word[NR] }
  450.  
  451. isolates words in a document over twice as fast as reading one line at a
  452. time and then examining each field with FS = "[^a-zA-Z]+".  
  453.  
  454. To remove comments from C code: 
  455.  
  456.     BEGIN { RS = "/\*([^*]|\*[^/])*\*/"  # comment is RS
  457.         ORS = " "
  458.     }
  459.  
  460.     { print }
  461.  
  462.     END { printf "\n" }
  463.  
  464.  
  465. 10. Multi-line records
  466.  
  467. Since mawk interprets RS as a regular expression, multi-line records are
  468. easy.  Setting RS = "\n\n+", makes one or more blank lines separate 
  469. records.  If FS = " " (the default), then single newlines, by the rules 
  470. for space above, become space.  
  471.  
  472.    For example, if a file is "a b\nc\n\n", RS = "\n\n+" and
  473.    FS = " ", then there is one record "a b\nc" with three
  474.    fields "a", "b" and "c".  Changing FS = "\n", gives two
  475.    fields "a b" and "c"; changing FS = "", gives one field
  476.    identical to the record.
  477.  
  478. For compatibility with (old) awk, setting RS = "" has the same
  479. effect on determining records as RS = "\n([ \t]*\n)+".
  480.  
  481. Most of the time when you change RS for mult-line records, you
  482. will also want to change ORS to "\n\n".
  483.  
  484. 11. User functions.
  485.  
  486. User defined functions are new.  They can be passed expressions by value
  487. or arrays by reference.  Function calls can be nested and support 
  488. recursion.  The syntax is 
  489.  
  490.     function  funcname( args ) {
  491.  
  492.     .... body
  493.  
  494.     }
  495.  
  496. Newlines are ignored after the ')' so the '{' can start on a different 
  497. line.  Inside the body, you can use a return statement 
  498.  
  499.     return expr
  500.     return
  501.  
  502. As in C, there is no distinction between functions and procedures.  A 
  503. function does not need an explicit return.  Extra arguments act as local
  504. variables.  For example, csplit(s, A) puts each character of s in array 
  505. A.  
  506.  
  507.     function  csplit(s, A,     i)
  508.     {
  509.       for(i=1; i <= length(s) ; i++)
  510.         A[i] = substr(s, i, 1)
  511.     }
  512.  
  513. Putting lots of space between the passed arguments and the local 
  514. variables is a convention that can be ignored if you don't like it.  
  515.  
  516. Dynamic regular expressions allow regular expressions to be passed to 
  517. user defined functions.  The following function gobble() is the lexical 
  518. scanner for a recursive descent parser, the whole program is in 
  519. examples/cdecl.awk.  
  520.  
  521.     function gobble( r,   x) # eat regular expression 
  522.         #  r off the front of global variable line
  523.  
  524.     {
  525.       if ( match( line, "^(" r ")") )
  526.       {
  527.         x = substr(line, 1, RLENGTH)
  528.         line = substr(line, RLENGTH)
  529.       }
  530.       else  x = ""
  531.  
  532.       return x
  533.     }
  534.  
  535. You can call a function before it is defined, but the function name and 
  536. the '(' must not be separated by white space to avoid confusion with 
  537. concatenation.  
  538.  
  539. 12. Other differences in mawk
  540.  
  541. The main differences between mawk and other awks have been discussed, RS
  542. as a regular expression and regular expression metacharacters don't have
  543. to be double escaped.  Here are some others: 
  544.  
  545.   VERSION  -- built-in variable holding version number of mawk.
  546.  
  547.     mawk 'BEGIN{print VERSION}'       shows it.
  548.  
  549.  
  550.   -D  --  command line flag causes mawk to dump to stderr 
  551.       a mawk assembler listing of the current program.
  552.       The program is executed by a stack machine internal
  553.       to mawk.  The op codes are in code.h, the machine in
  554.       execute.c.
  555.  
  556.   srand() --    
  557.       During initialization, mawk seeds the random number generator
  558.       by silently calling srand(), so calling srand() yourself is
  559.       unnecessary.  The main use of srand is to use srand(x) to get
  560.       a repeatable stream of random numbers.  Srand(x) returns x
  561.       and srand() returns the value of the system clock in some form
  562.       of ticks.
  563.  
  564.  
  565. 13. MsDOS
  566.  
  567. For a number of reasons, entering a mawk program on the command line 
  568. using command.com as your shell is an exercise in futility, so under 
  569. MsDOS the command syntax is 
  570.  
  571.     mawk [-Fs] optional_list_of_files
  572.  
  573. You'll get a prompt, and then type in the program.  The -f option works 
  574. as before.  
  575.  
  576. If you use a DOS shell that gives you a Unix style command line, to use 
  577. it you'll need to provide a C function reargv() that retrieves argc and 
  578. argv[] from your shell.  The details are in msdos/INSTALL.  
  579.  
  580. Some features are missing from the DOS version of mawk: No system(), and
  581. no input or output pipes.  To provide a hook to stderr, I've added 
  582.  
  583.     errmsg( "string" )
  584.  
  585. which prints "string\n" to stderr which will be the console and only the
  586. console under command.com.  A better solution would be to associate a 
  587. file with handle 2, so print and printf would be available.  Consider 
  588. the errmsg() feature as temporary.  
  589.  
  590. For compatibility with Unix, CR are silently stripped from input and LF 
  591. silently become CRLF on output.  
  592.  
  593. WARNING: If you write an infinite loop that does not print to the 
  594. screen, then you will have to reboot.  For example 
  595.  
  596.     x = 1 
  597.     while( x < 10 )  A[x] = x
  598.     x++
  599.  
  600. By mistake the x++ is outside the loop.  What you need to do is type 
  601. control break and the keyboard hardware will generate an interrupt and 
  602. the operating system will service that interrupt and terminate your 
  603. program, but unfortunately MsDOS does not have such a feature.  
  604.  
  605.  
  606. 14. Bugs
  607.  
  608. Currently mawk cannot handle \0 (NUL) characters in input files 
  609. otherwise mawk is 8 bit clean.  Also "a\0b", doesn't work right -- you 
  610. get "a".  You can't use \0 in regular expressions either.  
  611.  
  612.    printf "A string%c more string\n" , 0
  613.  
  614. does work, but more by luck than design since it doesn't work with 
  615. sprintf().  
  616.  
  617.  
  618. 15. Releases
  619.  
  620. This release is version 0.97.  After a reasonable period of time, any 
  621. bugs that appear will be fixed, and this release will become version 
  622. 1.0.  
  623.  
  624. Evidently features have been added to awk by Aho, Kernighan and 
  625. Weinberger since the 1988 release of the AWK book.  Version 1.1 will add
  626. whatever features are necessary to remain compatible with the language 
  627. as defined by its designers.  
  628.  
  629. After that ...  ? 
  630.  
  631. 16. Correspondence
  632.  
  633. Send bug reports or other correspondence to
  634.  
  635. Mike Brennan
  636. brennan@bcsaic.boeing.com
  637.  
  638. If you have some interesting awk programs, contributions to the examples
  639. directory would be appreciated.  
  640.